//
//  LBIndexPathSet.m
//  Auction
//
//  Created by Gary on 15/10/17.
//  Copyright © 2015年 Lebo. All rights reserved.
//

#import "LBIndexPathSet.h"
#import "LBIndexPathObject.h"
#import "Common.h"

@implementation LBIndexPathSet

- (instancetype)init
{
    self = [super init];
    if (self) {
        _set = [NSMutableSet set];
    }
    return self;
}

+ (instancetype)set {
    return [[LBIndexPathSet alloc] init];
}

- (NSUInteger)count {
    return _set.count;
}

- (id)objectAtIndexedSubscript:(NSUInteger)index {
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if ([object.indexPath indexAtPosition:0] != index) {
            continue;
        }
        bool isZero = true;
        for (int i = 1; i < object.indexPath.length; i++) {
            if ([object.indexPath indexAtPosition:i] != 0) {
                isZero = false;
                continue;
            }
        }
        if (isZero) {
            return object;
        }
    }
    return nil;
}

- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index {
    if (IsEmpty(object)) {
        return;
    }
    
    if ([self objectAtIndexedSubscript:index] == object) {
        return;
    }
    
    LBIndexPathObject *obj = object;
    if (!(obj.indexPath && obj.indexPath.length > 0)) {
        return;
    }
    
    NSUInteger length = obj.indexPath.length;
    NSUInteger indexes[length];
    indexes[0] = index;
    for (int i = 1; i < length; i++) {
        indexes[i] = 0;
    }
    
    NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexes length:length];
    [self removeObject:self[indexPath]];
    if (NSOrderedSame != [obj.indexPath compare:indexPath]) {
        obj.indexPath = indexPath;
    }
    
    [_set addObject:obj];
}

- (id)objectForKeyedSubscript:(id)key {
    NSIndexPath *indexPath = key;
    if (!indexPath) {
        return nil;
    }
    
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (NSOrderedSame == [object.indexPath compare:indexPath]) {
            return object;
        }
    }
    return nil;
}

- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)key {
    if (IsEmpty(key)) {
        return;
    }
    
    id oldObj = self[key];
    if (oldObj == object) {
        return;
    }
    
    if (IsEmpty(object)) {
        [self removeObject:oldObj];
        return;
    }
    
    LBIndexPathObject *obj = object;
    NSIndexPath *indexPath = (NSIndexPath *)key;
    if (NSOrderedSame != [obj.indexPath compare:indexPath]) {
        obj.indexPath = indexPath.copy;
    }
    [_set addObject:obj];
}

- (NSEnumerator *)objectEnumerator {
    return [_set objectEnumerator];
}

- (void)addObject:(id)object {
    if (IsEmpty(object)) {
        return;
    }
    
    LBIndexPathObject *obj = object;
    if (IsEmpty(obj.indexPath)) {
        return;
    }
    self[obj.indexPath] = obj;
}

- (void)removeObject:(id)object {
    if (!IsEmpty(object)) {
        [_set removeObject:object];
    }
}

- (NSArray *)frontIndexObjects:(NSUInteger)index {
    NSMutableArray *arr = [NSMutableArray array];
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (index == [object.indexPath indexAtPosition:0]) {
            [arr addObject:object];
        }
    }
    return [NSArray arrayWithArray:arr];
}

- (NSArray *)indexObjectsWithLength:(NSUInteger)length {
    NSMutableArray *arr = [NSMutableArray array];
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (object.indexPath.length == length) {
            [arr addObject:object];
        }
    }
    return [NSArray arrayWithArray:arr];
}

- (NSArray *)frontIndexObjects:(NSUInteger)index length:(NSUInteger)length {
    NSMutableArray *arr = [NSMutableArray array];
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (index == [object.indexPath indexAtPosition:0] && object.indexPath.length == length) {
            [arr addObject:object];
        }
    }
    return [NSArray arrayWithArray:arr];
}

- (NSArray *)frontIndexPathObjects:(NSIndexPath *)indexPath {
    if (!indexPath) {
        return [NSArray array];
    }
    
    NSMutableArray *arr = [NSMutableArray array];
    NSUInteger length = indexPath.length;
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (object.indexPath.length < length) {
            continue;
        }
        
        bool isEqual = true;
        for (int i = 0; i < length; i++) {
            isEqual = [indexPath indexAtPosition:i] == [object.indexPath indexAtPosition:i];
            if (!isEqual) {
                break;
            }
        }
        if (isEqual) {
            [arr addObject:object];
        }
    }
    return [NSArray arrayWithArray:arr];
}

- (NSArray *)frontIndexPathObjects:(NSIndexPath *)indexPath length:(NSUInteger)length {
    if (!indexPath || indexPath.length > length) {
        return [NSArray array];
    }
    
    NSMutableArray *arr = [NSMutableArray array];
    for (LBIndexPathObject *object in [_set objectEnumerator]) {
        if (object.indexPath.length < length) {
            continue;
        }
        
        bool isEqual = true;
        for (int i = 0; i < indexPath.length; i++) {
            isEqual = [indexPath indexAtPosition:i] == [object.indexPath indexAtPosition:i];
            if (!isEqual) {
                break;
            }
        }
        if (isEqual) {
            [arr addObject:object];
        }
    }
    return [NSArray arrayWithArray:arr];
}

@end
